<template>
  <CommonPage>
    <n-space>
      <NButton type="primary" size="small" @click="addConfigGroup">
        <i class="i-material-symbols:add mr-4 text-18" />
        新增配置组
      </NButton>
      <NButton type="primary" size="small" @click="addConfiguration(false)">
        <i class="i-material-symbols:add mr-4 text-18" />
        新增配置项
      </NButton>
    </n-space>
    <n-spin :show="spin">
      <n-tabs
        v-model:value="configGroupValue"
        type="card"
        closable
        animated
        mt-10
        min-h-500
        @update:value="handleTabChange"
        @close="close"
      >
        <n-tab-pane
          v-for="item in configGroupData"
          :key="item.id"
          :name="item.code"
          :tab="item.name"
        >
          <FormCreate v-model:api="fApi" :rule="ruleArray[item.id]" :option="option" />
        </n-tab-pane>
        <template #suffix>
          <n-space>
            <n-tooltip trigger="hover">
              <template #trigger>
                <n-button
                  strong
                  secondary
                  circle
                  type="primary"
                  size="small"
                  @click="editConfigGroup"
                >
                  <template #icon>
                    <div class="i-fe:edit" text-14 />
                  </template>
                </n-button>
              </template>
              编辑当前组
            </n-tooltip>

            <n-tooltip trigger="hover">
              <template #trigger>
                <n-button
                  strong
                  secondary
                  circle
                  type="primary"
                  size="small"
                  @click="addConfiguration(true)"
                >
                  <template #icon>
                    <div class="i-fe:plus" />
                  </template>
                </n-button>
              </template>
              添加该组配置项
            </n-tooltip>

            <n-tooltip trigger="hover">
              <template #trigger>
                <n-button
                  strong
                  secondary
                  circle
                  type="primary"
                  size="small"
                  @click="handleManagementConfiguration"
                >
                  <template #icon>
                    <div class="i-fe:settings" text-14 />
                  </template>
                </n-button>
              </template>
              管理该组配置
            </n-tooltip>
          </n-space>
        </template>
      </n-tabs>
    </n-spin>

    <ConfigGroupAddOrEdit
      ref="configGroupRef"
      @refresh="getConfigGroupListFn"
    />

    <ConfigAddOrEdit
      ref="configRef"
      :config-group-data="configGroupData"
      @refresh="refreshCurrentGroup"
    />

    <ManagementConfiguration
      ref="ManagementConfigurationRef"
      @edit-configuration="editConfiguration"
      @refresh="refreshCurrentGroup"
    />
  </CommonPage>
</template>

<script setup>
import { CommonPage } from '@/components'
// 导入 form-create
import formCreate from '@form-create/naive-ui'
import install from '@form-create/naive-ui/auto-import'
import { useTemplateRef } from 'vue'
import api from './api'
import ConfigAddOrEdit from './components/ConfigAddOrEdit.vue'
import ConfigGroupAddOrEdit from './components/ConfigGroupAddOrEdit.vue'
import ManagementConfiguration from './components/ManagementConfiguration.vue'

defineOptions({ name: 'Setting' })

formCreate.use(install)
// 获取 formCreate 组件
const FormCreate = formCreate.$form()

const spin = ref(false)
const fApi = ref(null)
const option = {
  onSubmit: async (formData) => {
    fApi.value.submitBtnProps({ loading: true })
    try {
      const { message } = await api.updateByKeys(formData)
      $message.success(message)
    }
    finally {
      fApi.value.submitBtnProps({ loading: false })
    }
  },
  resetBtn: { show: true },
  global: {
    InputNumber: {
      props: {
        min: 0,
      },
    },
    switch: {
      props: {
        checkedValue: '0',
        uncheckedValue: '1',
      },
    },
  },
}

onMounted(() => {
  getConfigGroupListFn()
})

const configGroupValue = ref('')
const configGroupData = ref([])
const ruleArray = ref([])

async function getConfigGroupListFn() {
  spin.value = true
  try {
    const response = await api.getConfigGroupList()
    configGroupData.value = response.data
    await getConfigListData(configGroupData.value[0].id)
  }
  finally {
    spin.value = false
  }
}

async function getConfigListData(id) {
  const params = {
    group_id: id,
  }
  ruleArray.value[id] = []
  const response = await api.getConfigList(params)
  ruleArray.value[id] = response.data.map((item) => {
    return formattedData(item)
  })

  configGroupValue.value = configGroupData.value.find(item => item.id === id).code
}

function formattedData(data) {
  const option = {
    type: data.input_type,
    title: data.name,
    field: data.key,
    value: formattedValue(data),
    info: { info: data.remark, align: 'left' },
  }
  if (data.config_select_data && data.config_select_data.length > 0) {
    option.options = data.config_select_data.map((item) => {
      return {
        label: item.key,
        value: item.value,
      }
    })
  }
  return option
}

function formattedValue(data) {
  let value = null
  if (data.input_type === 'InputNumber') {
    value = Number(data.value)
  }
  else {
    value = data.value
  }
  return value
}

const configGroupRef = useTemplateRef('configGroupRef')

function addConfigGroup() {
  configGroupRef.value?.handleOpen({
    action: 'add',
    title: '新增组',
    okText: '保存',
  })
}

function editConfigGroup() {
  const group = configGroupData.value.find(item => item.code === configGroupValue.value)
  configGroupRef.value?.handleOpen({
    action: 'edit',
    title: '编辑当前组',
    row: group,
    okText: '保存',
  })
}

const configRef = useTemplateRef('configRef')

function addConfiguration(flag) {
  let row = {}
  if (flag) {
    row.group_id = configGroupData.value.find(item => item.code === configGroupValue.value).id
  }
  else {
    row = {}
  }
  configRef.value?.handleOpen({
    action: 'add',
    title: '新增配置项',
    row,
    okText: '保存',
  })
}

function editConfiguration(row) {
  configRef.value?.handleOpen({
    action: 'edit',
    title: '编辑配置项',
    row,
    okText: '保存',
  })
}

async function handleTabChange(code) {
  const id = configGroupData.value.find(item => item.code === code).id
  if (ruleArray.value[id])
    return
  spin.value = true
  try {
    await getConfigListData(id)
  }
  finally {
    spin.value = false
  }
}

async function refreshCurrentGroup(data) {
  spin.value = true
  try {
    const id = configGroupData.value.find(item => item.id === data.group_id).id
    await getConfigListData(id)
  }
  finally {
    spin.value = false
  }
}

const ManagementConfigurationRef = useTemplateRef('ManagementConfigurationRef')

function handleManagementConfiguration() {
  const id = configGroupData.value.find(item => item.code === configGroupValue.value).id
  ManagementConfigurationRef.value?.handleOpen(id)
}

function close(code) {
  const configGroupItem = configGroupData.value.find(item => item.code === code)
  const d = $dialog.error({
    title: '提示',
    content: `你确定要删除《${configGroupItem.name}》配置组吗？`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      d.loading = true
      return new Promise((resolve) => {
        api
          .deleteConfigGroup({ ids: [configGroupItem.id] })
          .then((res) => {
            $message.success(res.message)
            const index = configGroupData.value.findIndex(item => item.id === configGroupItem.id)
            if (!~index)
              return
            configGroupData.value.splice(index, 1)
            if (code === configGroupValue.value) {
              const showConfigGroupData
                = configGroupData.value[Math.min(index, configGroupData.value.length - 1)]
              configGroupValue.value = showConfigGroupData.code
              showConfigGroupData.group_id = showConfigGroupData.id
              refreshCurrentGroup(showConfigGroupData)
            }
            resolve()
          })
          .finally(() => {
            d.loading = false
          })
      })
    },
  })
}
</script>
